﻿using System;
using System.Collections.Generic;
using System.Linq;
using Xenta.Enums;
using Xenta.Security;
using Xenta.Utils;

namespace Xenta.Operations
{
    public class ExportCatalogTags : ExportOperation,
        ISecuredOperation
    {
        #region Properties

        public IEnumerable<SecurityPolicy> SecurityPolicies
        {
            get
            {
                yield return new SecurityPolicy()
                    .IsAuthenticated()
                    .HasPermission("CTLG");
            }
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out IEnumerable<IDictionary<String, String>> result)
        {
            var ret = new List<IDictionary<String, String>>();
            var languages = uow.Execute(new SearchLanguages()).Result;

            foreach(var i in uow.Execute(new SearchCatalogTags()).Result)
            {
                var obj = new Dictionary<String, String>
                {
                    {"EntityID", i.EntityID.ToString()},
                    {"Flags", i.Flags.ToString()}
                };
                foreach(var l in languages)
                {
                    var t = i.Translation(l.EntityID);

                    obj.Add(l.Code, t != null ? t.Name : String.Empty);
                }
                ret.Add(obj);
            }
            result = ret;
        }

        #endregion
    }

    public class ExportCatalogCategories : ExportOperation,
        ISecuredOperation
    {
        #region Properties

        public IEnumerable<SecurityPolicy> SecurityPolicies
        {
            get
            {
                yield return new SecurityPolicy()
                    .IsAuthenticated()
                    .HasPermission("CTLG");
            }
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out IEnumerable<IDictionary<String, String>> result)
        {
            var ret = new List<IDictionary<String, String>>();
            var languages = uow.Execute(new SearchLanguages()).Result;
            foreach(var i in uow.Execute(new SearchCatalogCategories()).Result)
            {
                var obj = new Dictionary<String, String>
                {
                    {"EntityID", i.EntityID.ToString()},
                    {"ParentID", i.ParentID.ToString()},
                    {"Attributes", i.Attributes.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Flags", i.Flags.ToString()}
                };
                foreach(var l in languages)
                {
                    var t = i.Translation(l.EntityID);
                    obj.Add(l.Code, t != null ? t.Name : String.Empty);
                }
                ret.Add(obj);
            }
            result = ret;
        }

        #endregion
    }

    public class ExportCatalogItemGroups : ExportOperation,
        ISecuredOperation
    {
        #region Properties

        public IEnumerable<SecurityPolicy> SecurityPolicies
        {
            get
            {
                yield return new SecurityPolicy()
                    .IsAuthenticated()
                    .HasPermission("CTLG");
            }
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out IEnumerable<IDictionary<String, String>> result)
        {
            var ret = new List<IDictionary<String, String>>();
            var languages = uow.Execute(new SearchLanguages()).Result;
            foreach(var i in uow.Execute(new SearchCatalogItemGroups()).Result)
            {
                var obj = new Dictionary<String, String>
                {
                    {"EntityID", i.EntityID.ToString()},
                    {"SupplierID", i.Supplier.EntityID.ToString()},
                    {"Items", i.Items.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Flags", i.Flags.ToString()}
                };
                foreach(var l in languages)
                {
                    var t = i.Translation(l.EntityID);
                    obj.Add(l.Code, t != null ? t.Name : String.Empty);
                }
                ret.Add(obj);
            }
            result = ret;
        }

        #endregion
    }

    public class ExportCatalogItems : ExportOperation,
        ISecuredOperation
    {
        #region Properties

        public IEnumerable<SecurityPolicy> SecurityPolicies
        {
            get
            {
                yield return new SecurityPolicy()
                    .IsAuthenticated()
                    .HasPermission("CTLG");
            }
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out IEnumerable<IDictionary<String, String>> result)
        {
            var ret = new List<IDictionary<String, String>>();
            int? supplierID = null;
            int? categoryID = null;
            int index = 0;
            int count = 100;
            var sortDir = SortDirection.Ascending;
            var sortBy = CatalogItemSortBy.ID;

            if(Properties.ContainsKey("supplierID"))
                supplierID = Properties["supplierID"].ParseAs<Int32?>();
            if(Properties.ContainsKey("categoryID"))
                categoryID = Properties["categoryID"].ParseAs<Int32?>();
            if(Properties.ContainsKey("index"))
                index = Properties["index"].ParseAs(0);
            if(Properties.ContainsKey("count"))
                count = Properties["count"].ParseAs(100);
            if(Properties.ContainsKey("sortDir"))
                sortDir = Properties["sortDir"].ParseAs(SortDirection.Ascending);
            if(Properties.ContainsKey("sortBy"))
                sortBy = Properties["sortBy"].ParseAs(CatalogItemSortBy.ID);

            var languages = uow.Execute(new SearchLanguages()).Result;
            foreach(var i in uow.Execute(new SearchCatalogItems
            {
                SupplierID = supplierID,
                CategoryID = categoryID,
                Index = index,
                Count = count,
                SortDir = sortDir,
                SortBy = new [] {
                    sortBy
                }
            }).Result)
            {
                var obj = new Dictionary<String, String>
                {
                    {"EntityID", i.EntityID.ToString()},
                    {"SupplierID", i.Supplier.EntityID.ToString()},
                    {"Categories", i.Categories.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Groups", i.Groups.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Attributes", i.Attributes.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Tags", i.Tags.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Flags", i.Flags.ToString()}
                };
                foreach(var l in languages)
                {
                    var t = i.Translation(l.EntityID);
                    obj.Add(l.Code, t != null ? t.Name : String.Empty);
                }
                ret.Add(obj);
            }
            result = ret;
        }

        #endregion
    }

    public class ExportCatalogSuppliers : ExportOperation,
        ISecuredOperation
    {
        #region Properties

        public IEnumerable<SecurityPolicy> SecurityPolicies
        {
            get
            {
                yield return new SecurityPolicy()
                    .IsAuthenticated()
                    .HasPermission("CTLG");
            }
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out IEnumerable<IDictionary<String, String>> result)
        {
            var ret = new List<IDictionary<String, String>>();
            int? categoryID = null;
            int index = 0;
            int count = 100;
            var sortDir = SortDirection.Ascending;
            var sortBy = CatalogSupplierSortBy.ID;

            if(Properties.ContainsKey("categoryID"))
                categoryID = Properties["categoryID"].ParseAs<Int32?>();
            if(Properties.ContainsKey("index"))
                index = Properties["index"].ParseAs(0);
            if(Properties.ContainsKey("count"))
                count = Properties["count"].ParseAs(100);
            if(Properties.ContainsKey("sortDir"))
                sortDir = Properties["sortDir"].ParseAs(SortDirection.Ascending);
            if(Properties.ContainsKey("sortBy"))
                sortBy = Properties["sortBy"].ParseAs(CatalogSupplierSortBy.ID);

            var languages = uow.Execute(new SearchLanguages()).Result;
            foreach(var i in uow.Execute(new SearchCatalogSuppliers
            {
                CategoryID = categoryID,
                Index = index,
                Count = count,
                SortDir = sortDir,
                SortBy = new []
                {
                    sortBy
                }
            }).Result)
            {
                var obj = new Dictionary<String, String>
                {
                    {"EntityID", i.EntityID.ToString()},
                    {"Categories", i.Categories.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Attributes", i.Attributes.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Tags", i.Tags.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Managers", i.Managers.Select(x => x.EntityID.ToString()).Merge(",")},
                    {"Flags", i.Flags.ToString()}
                };
                foreach(var l in languages)
                {
                    var t = i.Translation(l.EntityID);
                    obj.Add(l.Code, t != null ? t.Name : String.Empty);
                }
                ret.Add(obj);
            }
            result = ret;
        }

        #endregion
    }
}
